#!/bin/sh
#

#############################################################
# AnripDdns v6.1.1
#
# Dynamic DNS using DNSPod API
#
# Author: Rehiy, https://github.com/rehiy
#                https://www.anrip.com/?s=dnspod
# Collaborators: ProfFan, https://github.com/ProfFan
#
# Usage: please refer to `ddnspod.sh`
#
#############################################################



# TokenID,Token

export arToken=""

# Get WAN IPv4

arWanIp4() {

    local hostIp

    local lanIps="^$"

    lanIps="$lanIps|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^169\.254\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)"

    case $(uname) in
        'Linux')
            hostIp=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev "$lanIps")
        ;;
        Darwin|FreeBSD)
            hostIp=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | grep -Ev "$lanIps")
        ;;
    esac

    if [ -z "$hostIp" ]; then
        if type wget >/dev/null 2>&1; then
            hostIp=$(wget -q -O- https://v4.myip.la)
        else
            hostIp=$(curl -s https://v4.myip.la)
        fi
    fi

    if [ -z "$hostIp" ]; then
        echo "arWanIp4 - Can't get ip address"
        logger -t DNSpod_DDNS "无法获取ip地址"
        return 1
    fi

    if [ -z "$(echo $hostIp | grep -E '^[0-9\.]+$')" ]; then
        echo "arWanIp4 - Invalid ip address $hostIp"
        logger -t DNSpod_DDNS "无效ip地址：$hostIp"
        return 1
    fi

    echo $hostIp

}

# Get WAN IPv6

arWanIp6() {

    local hostIp

    local lanIps="(^$)|(^::1$)|(^[fF][eE][8-9a-fA-F])"

    case $(uname) in
        'Linux')
            hostIp=$(ip -o -6 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4,substr($NF,0,length($NF)-3)}' | sed 's/fore/2592000/g' | sort -k 2 -n | cut -d/ -f1 | grep -Ev "$lanIps" | head -n 1)
        ;;
        Darwin|FreeBSD)
            hostIp=$(ifconfig | grep "inet6 " | awk '{print $2}' | grep -Ev "$lanIps" | head -n 1)
        ;;
    esac

    if [ -z "$hostIp" ]; then
        if type wget >/dev/null 2>&1; then
            hostIp=$(wget -q -O- https://v6.myip.la)
        else
            hostIp=$(curl -s https://v6.myip.la)
        fi
    fi

    if [ -z "$hostIp" ]; then
        echo "arWanIp6 - Can't get ip address"
        return 1
    fi

    if [ -z "$(echo $hostIp | grep -E '^[0-9a-fA-F:]+$')" ]; then
        echo "arWanIp6 - Invalid ip address"
        return 1
    fi

    echo $hostIp

}

# Dnspod Bridge
# Args: type data

arDdnsApi() {

    local agent="AnripDdns/6.1.0(wang@rehiy.com)"

    local apiurl="https://dnsapi.cn/${1:?'Info.Version'}"
    local params="login_token=$arToken&format=json&$2"

    if type wget >/dev/null 2>&1; then
        wget -q -O- --no-check-certificate -U $agent --post-data $params $apiurl
    else
        curl -s -A $agent -d $params $apiurl
    fi

}

# Fetch Ids of Domain and Record
# Args: recordType domain subdomain

arDdnsIds() {

    local errMsg

    local domainId
    local recordId

    # Get Domain Id
    domainId=$(arDdnsApi "Domain.Info" "domain=$2")
    domainId=$(echo $domainId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

    if ! [ "$domainId" -gt 0 ] 2>/dev/null ;then
        errMsg=$(echo $domainId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
        echo "arDdnsIds - $errMsg"
        logger -t DNSpod_DDNS "arDdnsIds - $errMsg"
        return 1
    fi

    # Get Record Id
    recordId=$(arDdnsApi "Record.List" "domain_id=$domainId&sub_domain=$3&record_type=$1")
    recordId=$(echo $recordId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

    if ! [ "$recordId" -gt 0 ] 2>/dev/null ;then
        errMsg=$(echo $recordId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
        echo "arDdnsIds - $errMsg"
        logger -t DNSpod_DDNS "arDdnsIds - $errMsg"
        return 1
    fi

    echo $domainId $recordId
    logger -t DNSpod_DDNS "$domainId $recordId"
}

# Fetch Record Ip
# Args: domainId recordId

arDdnsRecordIp() {

    local errMsg

    local recordIp

    # Get Record Ip
    recordIp=$(arDdnsApi "Record.Info" "domain_id=$1&record_id=$2")
    recordIp=$(echo $recordIp | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')

    # Output Record Ip
    case "$recordIp" in
        [0-9a-fA-F]*)
            echo $recordIp
            logger -t DNSpod_DDNS "$recordIp"
            return 0
        ;;
        *)
            errMsg=$(echo $recordIp | sed 's/.*"message":"\([^\"]*\)".*/\1/')
            echo "arDdnsRecordIp - $errMsg"
            logger -t DNSpod_DDNS "arDdnsRecordIp - $errMsg"
            return 1
        ;;
    esac

}

# Update Record Ip
# Args: domainId recordId subdomain hostIp recordType

arDdnsUpdate() {

    local errMsg

    local recordRs
    local recordIp
    local recordCd

    if [ -z "$5" ]; then
        echo "arDdnsUpdate - Args number error"
        logger -t DNSpod_DDNS "arDdnsUpdate - Args number error"
        return 1
    fi

    # Update Ip
    recordRs=$(arDdnsApi "Record.Modify" "domain_id=$1&record_id=$2&sub_domain=$3&record_type=$5&value=$4&record_line=%e9%bb%98%e8%ae%a4")
    recordIp=$(echo $recordRs | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')
    recordCd=$(echo $recordRs | sed 's/.*{"code":"\([0-9]*\)".*/\1/')

    # Output Result
    if [ "$recordIp" = "$4" ] && [ "$recordCd" = "1" ]; then
        echo "arDdnsUpdate - success"
        logger -t DNSpod_DDNS "arDdnsUpdate - success"
        return 0
    else
        errMsg=$(echo $recordRs | sed 's/.*,"message":"\([^"]*\)".*/\1/')
        echo "arDdnsUpdate - $errMsg"
        logger -t DNSpod_DDNS "arDdnsUpdate - $errMsg"
        return 1
    fi

}

# DDNS Check
# Args: Main Sub
arDdnsCheck() {

    local errCode

    local recordType
    local hostIp

    local ddnsIds
    local lastIp
    local postRs

    echo "Fetching Host Ip"
    logger -t DNSpod_DDNS "获取主机IP"
    if [ "$3" = "6" ]; then
        recordType=AAAA
        hostIp=$(arWanIp6)
    else
        recordType=A
        hostIp=$(arWanIp4)
    fi

    errCode=$?
    echo "> Host Ip: $hostIp"
    logger -t DNSpod_DDNS "主机IP: $hostIp"
    echo "> Record Type: $recordType"
    logger -t DNSpod_DDNS "记录类型: $recordType"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    echo "Fetching Ids of $2.$1"
    logger -t DNSpod_DDNS "抓取Id： $2.$1"
    ddnsIds=$(arDdnsIds "$recordType" "$1" "$2")

    errCode=$?
    echo "> Domain Ids: $ddnsIds"
    logger -t DNSpod_DDNS "域名Ids: $ddnsIds"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    echo "Checking Record for $2.$1"
    logger -t DNSpod_DDNS "检查记录：$2.$1"
    lastIp=$(arDdnsRecordIp $ddnsIds)

    errCode=$?
    echo "> Last Ip: $lastIp"
    logger -t DNSpod_DDNS "上一次的IP: $lastIp"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    if [ "$lastIp" = "$hostIp" ]; then
        echo "> Last Ip is the same as host Ip"
        logger -t DNSpod_DDNS "> 上一次的IP与主机记录值相同 <"
        return 0
    fi

    echo "Updating Record for $2.$1"
    logger -t DNSpod_DDNS "Updating Record for $2.$1"
    postRs=$(arDdnsUpdate $ddnsIds "$2" "$hostIp" "$recordType")

    errCode=$?
    echo "> $postRs"
    logger -t DNSpod_DDNS "> $postRs"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

}
arToken=12345,7676f344eaeaea9074c123451234512d
arDdnsCheck test.org hijunaikk.site 6
